home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * xanim.c
- *
- * Copyright (C) 1990,1991,1992 by Mark Podlipec.
- * All rights reserved.
- *
- * This software may be freely copied, modified and redistributed
- * without fee provided that this copyright notice is preserved
- * intact on all copies and modified copies.
- *
- * There is no warranty or other guarantee of fitness of this software.
- * It is provided solely "as is". The author(s) disclaim(s) all
- * responsibility and liability with respect to this software's usage
- * or its effect upon hardware or computer systems.
- *
- */
-
- #define DA_REV 2.29
-
- /*
- *
- */
-
- #include <X11/Xlib.h>
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/Shell.h>
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/signal.h>
- #include <sys/param.h>
- #include <sys/times.h>
- #include <memory.h>
- #include <ctype.h>
- #include "mytypes.h"
- #include "xanim.h"
- #include "xanim_x11.h"
-
- void TheEnd();
- void TheEnd1();
- void Usage();
- ULONG GetWord();
- ULONG GetHalfWord();
- void ShowAnimation();
- void ShowAction();
- int Determine_Anim_Type();
- void Cycle_It();
-
- /*
- * Global X11 display configuation variables
- *
- * These are set by X11_Pre_Setup();
- *
- */
-
- int x11_depth;
- int x11_class;
- int x11_bytes_pixel;
- int x11_cmap_flag;
- int x11_cmap_size;
- int x11_display_type;
-
- /*
- * Each animation is broken up into a series of individual actions.
- * For example, a gif image would become two actions, 1 to setup the
- * colormap and 1 to display the image.
- *
- * ACTION is defined in xanim.h.
- *
- * action_cnt is a global variable that points to the next unused action.
- * Currently, individual routines access this. This will change.
- *
- * action_start is a variable passed to the Read_Animation routines, It
- * keeps track of the 1st action available to routine.
- *
- */
- ACTION action[2000];
- int action_cnt;
- int action_start;
-
- /*
- * This structure is set up for each animation file. It keeps track of
- * special flags and which animation type.
- *
- * anim_cnt indexes the next available anim structure.
- *
- * anim_type is one of IFF_,FLI_,GIF_,TXT_,FADE_ANIM.
- *
- * merged_anim_flags is the or of all anims read in. FLI's anims need
- * only 1 buffer. IFF anims need two. This allows software to allocate
- * for the worst case.
- *
- */
- ANIM_HDR anim[50];
- int anim_cnt;
- int anim_type;
- int merged_anim_flags;
-
-
- /*
- * cmap keeps track of the current colors to the screen.
- *
- * hmap is IFF HAM specific and is needed to decode HAM images into 332
- * and into 24bits when supported.
- *
- */
- ColorReg *cmap = 0;
- ColorReg ham_map[HMAP_SIZE];
-
- /*
- * Global variable to keep track of Anim type
- */
- int filetype;
-
- /*
- * Global variables to keep track of current width, height, num of colors and
- * number of bit planes respectively.
- *
- * the max_ variable are used for worst case allocation. Are useful for Anims
- * that have multiple image sizes.
- *
- * image_size and max_image_size are imagex * imagey, etc.
- */
- int imagex, imagey, max_imagex, max_imagey;
- int disp_y, max_disp_y;
- int imagec, imaged;
- int image_size;
- int max_image_size;
-
- /*
- * These variable keep track of where we are in the animation.
- * cur_file keeps track of which file we're displaying. (ie anim[ cur_file] )
- * cur_floop keeps track of how many times we've looped a file.
- * cur_frame keeps track of which frame(action) we're on.
- *
- * cycle_wait and cycle_cnt are used for color cycling.
- *
- * start_file indicates whether this is the 1st time we've looped a file
- * or not. Is used to initialize variables and resize window if necessary.
- *
- */
- int cur_file,cur_floop,cur_frame;
- int cycle_wait,cycle_cnt;
- int start_file;
- int anim_forward_flag;
- /*
- * Image buffers.
- * im_buff1 is used for double buffered anims(IFF).
- * hbuff is need as temporary space for storing the 332 images with HAM(IFF).
- *
- * pic is a pointer to im_buff0 or im_buff1 during double buffering.
- *
- */
- char *im_buff0,*im_buff1,*pic,*hbuff;
-
- /*
- * Global flags that are set on command line.
- */
- int buff_flag;
- int loopeach_flag;
- int anim_flags;
- int cycle_on_flag;
- int debug_flag;
- int verbose;
- int jiffy_flag;
- int fade_flag,fade_time;
- int noresize_flag;
- int anim_running;
- int update_flag;
- int optimize_flag;
-
- /*
- * old_dlta is used for optimizing screen updates for IFF and FLI animations.
- *
- * act is a global pointer to the current action.
- *
- */
- ACT_IFF_DLTA_HDR old_dlta[2];
- ACTION *act;
-
- /*
- * This function (hopefully) provides a clean exit from our code.
- */
- void TheEnd()
- {
- if (action_cnt > 0 )
- {
- int i;
- for(i=0;i<action_cnt;i++)
- if (action[i].data != 0) free(action[i].data);
- }
- if (im_buff0) free(im_buff0);
- if (im_buff1) free(im_buff1);
- if (hbuff) free(hbuff);
- if (cmap) free(cmap);
- /*if (theDisp) XtCloseDisplay(theDisp); */
- exit(0);
- }
-
- /*
- * just prints a message before calling TheEnd()
- */
- void TheEnd1(err_mess)
- char *err_mess;
- {
- fprintf(stderr,"%s\n",err_mess);
- TheEnd();
- }
-
- /*
- * This function attempts to expain XAnim's usage if the command line
- * wasn't correct.
- */
- void Usage()
- {
- fprintf(stderr,"Usage:\n\n");
- fprintf(stderr,"xanim [ [+|-]opts ...] animfile [ [ [-opts] animfile] ... ]\n");
- fprintf(stderr,"\n");
- fprintf(stderr,"A + turns the following options on and a - turns them off.\n");
- fprintf(stderr,"Option f,j and l ignore leading + and -'s.\n");
- fprintf(stderr,"\n");
- fprintf(stderr,"Options:\n");
- fprintf(stderr,"\n");
- fprintf(stderr," b buffers images ahead of time. default is off.\n");
- fprintf(stderr," c disable looping for nonlooping iff anims.\n");
- fprintf(stderr," default is off.\n");
- fprintf(stderr," f# fade to black in 16 frames. frame delay=#ms\n");
- fprintf(stderr," default is off.\n");
- fprintf(stderr," i Interlace flag. Reduce image height by two\n");
- fprintf(stderr," default is off.\n");
- fprintf(stderr," j# # is number of milliseconds between frames\n");
- fprintf(stderr," (default is 17 unless specified inside the\n");
- fprintf(stderr," the animation itself).\n");
- fprintf(stderr," l# # is number of loops(default = 1) through each\n"); fprintf(stderr," file before moving next file.\n");
- fprintf(stderr," r turn color cycling off. default is on\n");
- fprintf(stderr," o turns on certain optimizations. Turning this\n");
- fprintf(stderr," off would only be useful if you are\n");
- fprintf(stderr," buffering the anim and wish to run it\n");
- fprintf(stderr," backwards. default is on.\n");
- fprintf(stderr," s prevents window from resizing to match image\n");
- fprintf(stderr," size. Window is the size of largest image.\n");
- fprintf(stderr," default is on.\n");
- fprintf(stderr," u when single stepping, anim is played until\n");
- fprintf(stderr," image is updated/changed.(a new cmap is\n");
- fprintf(stderr," not considered an update) default is on.\n");
- fprintf(stderr," v verbose mode. default is off.\n");
- fprintf(stderr,"\n");
- fprintf(stderr,"Window commands when anim is NOT running\n");
- fprintf(stderr,"\n");
- fprintf(stderr," q quit\n");
- fprintf(stderr," g For cycling images, move to next file\n");
- fprintf(stderr," s Stop cycling\n");
- fprintf(stderr," r Restore Colors after stopping cycling\n");
- fprintf(stderr," space toggle. starts/stops animation\n");
- fprintf(stderr," , go back one frame within file\n");
- fprintf(stderr," . go forward one frame within file\n");
- fprintf(stderr," < go back to start of previous file\n");
- fprintf(stderr," > go forward to start of next file\n");
- fprintf(stderr,"\n");
-
- exit(0);
- }
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char *filename,*in;
- int i,j;
-
- /*
- * Initialize global variables.
- */
- theDisp = NULL;
-
- im_buff0 = 0;
- im_buff1 = 0;
- hbuff = 0;
- max_imagex = 0;
- max_imagey = 0;
- max_disp_y = 0;
-
- anim_cnt = 0;
- action_cnt = 0;
-
- anim_forward_flag = TRUE;
- anim_running = TRUE;
- buff_flag = FALSE;
- cycle_on_flag = TRUE;
- noresize_flag = FALSE;
- verbose = FALSE;
- debug_flag = FALSE;
- update_flag = TRUE;
- optimize_flag = TRUE;
-
- anim_flags = ANIM_CYCON;
- merged_anim_flags = 0;
- loopeach_flag = 1;
- jiffy_flag = 0;
-
-
- /* What rev are we running
- */
- fprintf(stderr,"XAnim Rev %2.2f Beta by Mark Podlipec (c) 1990,1991,1992\n",DA_REV);
-
- /* quick command line check.
- */
- if (argc<2) Usage();
-
- /* setup for dying time.
- */
- signal(SIGINT,TheEnd);
-
- /* PreSet of X11 Display to find out what we're dealing with
- */
- X11_Pre_Setup();
-
- cmap = (ColorReg *) malloc( x11_cmap_size * sizeof(ColorReg) );
-
- /* Parse command line.
- */
- for(i=1;i<argc;i++)
- {
- in = argv[i];
- if ( (in[0]=='-') || (in[0]=='+') )
- {
- int len,opt_on;
-
- if (in[0]=='-') opt_on = FALSE;
- else opt_on = TRUE;
-
- len = strlen(argv[i]);
- j = 1;
- while( (j<len) && (in[j]!=0) )
- {
- switch(in[j])
- {
- case 'b':
- buff_flag = opt_on;
- j++;
- break;
- case 'c':
- if (opt_on==TRUE) anim_flags |= ANIM_NOLOP;
- else anim_flags &= (~ANIM_NOLOP);
- j++;
- break;
- case 'd':
- debug_flag = opt_on;
- if (opt_on==TRUE) anim_flags |= ANIM_DEBUG;
- else anim_flags &= (~ANIM_DEBUG);
- j++;
- break;
- case 'f':
- fade_time = atoi(&in[2]);
- if (fade_time <= 0) fade_flag = 0;
- else fade_flag = 1;
- j+=len;
- break;
- case 'l':
- loopeach_flag = atoi(&in[2]);
- if (loopeach_flag<=0) loopeach_flag = 1;
- j+=len;
- break;
- case 'i':
- if (opt_on==TRUE) anim_flags |= ANIM_LACE;
- else anim_flags &= (~ANIM_LACE);
- j++;
- break;
- case 'j':
- jiffy_flag = atoi(&in[2]);
- if (jiffy_flag<=0) jiffy_flag = 1;
- j+=len;
- break;
- case 'o':
- optimize_flag = opt_on;
- j++;
- break;
- case 'r':
- cycle_on_flag = opt_on;
- if (opt_on==TRUE) anim_flags |= ANIM_CYCON;
- else anim_flags &= (~ANIM_CYCON);
- j++;
- break;
- case 's':
- noresize_flag = opt_on;
- j++;
- break;
- case 'u':
- update_flag = opt_on;
- j++;
- break;
- case 'v':
- verbose = opt_on;
- j++;
- break;
- case '-':
- opt_on = FALSE;
- j++;
- break;
- case '+':
- opt_on = TRUE;
- j++;
- break;
- default:
- Usage();
- } /* end of option switch */
- } /* end of loop through options */
- } /* end of if - */
- else
- /* If no hyphen in front of argument, assume it's a file.
- */
- {
- action_start = action_cnt;
- filename = argv[i];
-
- /* default is FLI */
- anim_type = Determine_Anim_Type(filename);
- anim[anim_cnt].anim_type = anim_type;
- switch(anim_type)
- {
- int action_number,ii;
- case IFF_ANIM:
- if (verbose) fprintf(stderr,"Reading IFF File %s\n",filename);
- merged_anim_flags |= ANIM_IFF;
- IFF_Read_File(filename);
- if (buff_flag) IFF_Buffer_Action(action_start);
- break;
- case GIF_ANIM:
- if (verbose) fprintf(stderr,"Reading GIF File %s\n",filename);
- GIF_Read_File(filename,1);
-
- action_number = action_cnt - action_start;
- anim[anim_cnt].frame_lst =
- (int *)malloc(sizeof(int) * (action_number+1));
- if (anim[anim_cnt].frame_lst == NULL)
- TheEnd1("GIF_ANIM: couldn't malloc for frame_lst\0");
- for(ii=0; ii < action_number; ii++)
- anim[anim_cnt].frame_lst[ii]=action_start+ii;
- anim[anim_cnt].frame_lst[action_number] = -1;
- anim[anim_cnt].loop_frame = 0;
- anim[anim_cnt].last_frame = action_number-1;
- break;
- case TXT_ANIM:
- if (verbose) fprintf(stderr,"Reading TXT File %s\n",filename);
- TXT_Read_File(filename);
- break;
- case FLI_ANIM:
- if (verbose) fprintf(stderr,"Reading FLI File %s\n",filename);
- Read_Fli_File(filename);
- if (buff_flag) Fli_Buffer_Action(action_start);
-
- action_number = action_cnt - action_start;
- anim[anim_cnt].frame_lst =
- (int *)malloc(sizeof(int) * (action_number+1));
- if (anim[anim_cnt].frame_lst == NULL)
- TheEnd1("GIF_ANIM: couldn't malloc for frame_lst\0");
- for(ii=0; ii < action_number; ii++)
- anim[anim_cnt].frame_lst[ii]=action_start+ii;
- anim[anim_cnt].frame_lst[action_number] = -1;
- anim[anim_cnt].loop_frame = 0;
- anim[anim_cnt].last_frame = action_number-1;
- break;
- default:
- fprintf(stderr,"Unknown or unsupported animation type\n");
- break;
- }
- /*
- * Setup up anim header.
- */
- anim[anim_cnt].imagex = imagex;
- anim[anim_cnt].imagey = imagey;
- anim[anim_cnt].imagec = imagec;
- anim[anim_cnt].imaged = imaged;
- anim[anim_cnt].anim_flags = anim_flags;
- anim[anim_cnt].loop_num = loopeach_flag;
- merged_anim_flags |= anim_flags;
-
- anim_cnt++;
-
- if (imagex > max_imagex) max_imagex = imagex;
- if (imagey > max_imagey) max_imagey = imagey;
- if (anim_flags & ANIM_LACE)
- {
- if ((imagey/2) > max_disp_y) max_disp_y = imagey/2;
- }
- else
- {
- if ( imagey > max_disp_y) max_disp_y = imagey;
- }
-
- /*
- * If fade flag is on, basically insert a fade anim.
- */
- if (fade_flag && (x11_cmap_flag == TRUE) )
- {
- int ii;
- anim[anim_cnt].anim_type = FADE_ANIM;
-
- /* Fade to Black action */
- action_start = action_cnt;
- action[action_cnt].type = ACT_FADE;
- action[action_cnt].time = fade_time;
- action[action_cnt].data = 0;
- action_cnt++;
- /* Blank screen so next CMAP doesn't show */
- action[action_cnt].type = ACT_FLI_BLACK;
- action[action_cnt].time = fade_time;
- action[action_cnt].data = 0;
- action_cnt++;
-
-
- /*
- * Setup frame list to call ACT_FADE sixteen times and FLI_BLACK once.
- */
- anim[anim_cnt].frame_lst = (int *)malloc(sizeof(int) * (18));
- if (anim[anim_cnt].frame_lst == NULL)
- TheEnd1("FADE_ANIM: couldn't malloc for frame_lst\0");
- for(ii=0;ii<16;ii++) anim[anim_cnt].frame_lst[ii] = action_start;
- anim[anim_cnt].frame_lst[16] = action_start+1;
- /* Last frame is always -1
- */
- anim[anim_cnt].frame_lst[17] = -1;
-
- anim[anim_cnt].imagex = imagex;
- anim[anim_cnt].imagey = imagey;
- anim[anim_cnt].imagec = imagec;
- anim[anim_cnt].imaged = imaged;
- anim[anim_cnt].anim_flags = anim_flags;
- anim[anim_cnt].loop_num = 1;
- anim[anim_cnt].loop_frame = 0;
- anim[anim_cnt].last_frame = 16;
- anim_cnt++;
- } /* end of fade anim insertion */
-
- } /* end of read in file */
- } /* end of loopin through arguments */
-
- /* No anims listed
- */
- if (anim_cnt == 0) Usage();
-
- /* Set up X11 Display
- */
-
- if (noresize_flag==TRUE)
- X11_Setup(max_imagex,max_disp_y,max_imagex,max_disp_y);
- else
- X11_Setup(max_imagex,max_disp_y,anim[0].imagex,
- (anim[0].anim_flags & ANIM_LACE)?(anim[0].imagey/2):(anim[0].imagey) );
-
- /* Start off Animation.
- */
- ShowAnimation();
- /* Wait for user input.
- */
- xanim_events();
-
- /* Self-Explanatory
- */
- TheEnd();
- }
-
- /* Routine to read a long word.
- * yeah, I know macro's are faster.
- */
- ULONG GetWord(fp)
- FILE *fp;
- {
- ULONG ret;
-
- ret = fgetc(fp);
- ret |= fgetc(fp) << 8;
- ret |= fgetc(fp) << 16;
- ret |= fgetc(fp) << 24;
- return ret;
- }
-
- /* Routine to read a half word.
- * yeah, I know macro's are faster.
- */
- ULONG GetHalfWord(fp)
- FILE *fp;
- {
- ULONG ret;
-
- ret = fgetc(fp);
- ret |= fgetc(fp) << 8;
- return ret;
- }
-
-
- /*
- * ShowAnimation allocates and sets up required image buffers and
- * initializes animation variables.
- * It then kicks off the animation.
- */
- void ShowAnimation()
- {
-
- max_image_size = max_imagex * max_imagey;
- im_buff0 = (char *) malloc( max_image_size * x11_bytes_pixel);
- if (im_buff0 == 0) TheEnd1("ShowAnimation: im_buff0 malloc failed");
- if (merged_anim_flags & ANIM_IFF)
- {
- im_buff1 = (char *) malloc( max_image_size * x11_bytes_pixel);
- if (im_buff1 == 0) TheEnd1("ShowAnimation: im_buff1 malloc failed");
-
- if ( (merged_anim_flags & ANIM_HAM) || (merged_anim_flags & ANIM_LACE) )
- {
- hbuff = (char *) malloc( max_image_size * x11_bytes_pixel);
- if (hbuff == 0) TheEnd1("ShowAnimation: hbuff malloc failed");
- }
- old_dlta[0].minx = max_imagex; old_dlta[0].miny = max_imagey;
- old_dlta[0].maxx = 0; old_dlta[0].maxy = 0;
- old_dlta[1].minx = max_imagex; old_dlta[1].miny = max_imagey;
- old_dlta[1].maxx = 0; old_dlta[1].maxy = 0;
- }
- pic = im_buff0;
-
- cur_file = 0;
- cur_floop = 0;
- cur_frame = 0;
- start_file = 0;
- cycle_wait = 0;
- cycle_cnt = 0;
-
- XtAppAddTimeOut(theContext, 1, ShowAction, NULL);
- }
-
- /*
- * This is the heart of this program. It does each action and then calls
- * itself with a timeout via the XtAppAddTimeOut call.
- */
- void ShowAction(nothing,id)
- char *nothing;
- XtIntervalId *id;
- {
- int screen_updated;
- int t_frame_start,t_frame_end,t_frame_int;
- struct tms tms3;
-
- screen_updated = FALSE;
- /* If color cycling, wait for user go ahead.
- */
- if (cycle_wait && cycle_cnt)
- {
- XtAppAddTimeOut(theContext, 10, ShowAction, NULL);
- return;
- }
-
- /* sanity check.
- */
- if (cur_file >= anim_cnt) return;
-
- /* 1st throught this particular file.
- * Resize if necessary and init required variables.
- */
- if (start_file == 0)
- {
- start_file=1;
- cycle_wait=0;
- anim_flags = anim[cur_file].anim_flags;
-
- if (anim_flags & ANIM_DEBUG) debug_flag = 1;
- else debug_flag = 0;
- if (anim_flags & ANIM_CYCON) cycle_on_flag = 1;
- else cycle_on_flag = 0;
-
- /* if interlaced flag then compare half-height images to current settings.
- */
- if (noresize_flag == FALSE)
- {
- if ( anim[cur_file].anim_flags & ANIM_LACE )
- {
- if ( (imagex != anim[cur_file].imagex)
- || (disp_y != (anim[cur_file].imagey/2)) )
- XResizeWindow(theDisp,mainW,anim[cur_file].imagex,
- anim[cur_file].imagey/2);
- }
- else
- {
- if ( (imagex != anim[cur_file].imagex)
- || (disp_y != anim[cur_file].imagey) )
- XResizeWindow(theDisp,mainW,anim[cur_file].imagex,
- anim[cur_file].imagey);
- }
- }
- else
- {
- if (imagex > anim[cur_file].imagex)
- XClearArea(theDisp,mainW,anim[cur_file].imagex,0, 0,0,FALSE);
- if ( anim[cur_file].anim_flags & ANIM_LACE )
- {
- if (disp_y > (anim[cur_file].imagey/2) )
- XClearArea(theDisp,mainW,0,(anim[cur_file].imagey/2), 0,0,FALSE);
- }
- else
- {
- if (disp_y > anim[cur_file].imagey )
- XClearArea(theDisp,mainW,0,anim[cur_file].imagey, 0,0,FALSE);
- }
- }
- /* Initialize variables
- */
- imagex = anim[cur_file].imagex;
- imagey = anim[cur_file].imagey;
- imaged = anim[cur_file].imaged;
- imagec = anim[cur_file].imagec;
- image_size = imagex * imagey;
-
- /*
- * What's this!? Direct access to X11 structures. tsch tsch.
- *
- * With half-height images, I fool X11 by telling it the image is
- * twice as wide and half as high, then only display left half of image.
- *
- * NOTE: when adding TrueColor bytes_per_line needs modification.
- */
- if (anim_flags & ANIM_LACE)
- {
- theImage->width = 2*imagex;
- theImage->height = imagey/2;
- theImage->bytes_per_line = 2*imagex * x11_bytes_pixel;
- disp_y = imagey/2;
- }
- else
- {
- theImage->width = imagex;
- theImage->height = imagey;
- theImage->bytes_per_line = imagex * x11_bytes_pixel;
- disp_y = imagey;
- }
- }
-
- /* OK. A quick sanity check and then we act.
- */
- if ( (anim[cur_file].frame_lst[cur_frame] >= 0)
- && (anim[cur_file].frame_lst[cur_frame] < action_cnt) )
- {
- /* initialize act and get the current time.
- */
- act = &action[ anim[cur_file].frame_lst[cur_frame] ];
- t_frame_start = times(&tms3);
- t_frame_int = act->time;
-
-
- /* lesdoit */
- switch(act->type)
- {
- /*
- * NOP and DELAY don't change anything but can have timing info
- * that might prove useful. ie dramatic pauses :^)
- */
- case ACT_NOP:
- break;
- case ACT_DELAY:
- break;
- /*
- * Change Color Map.
- */
- case ACT_CMAP:
- if (x11_cmap_flag == TRUE)
- {
- int off,j;
- ColorReg *cptr;
- CMAP_HDR *cmap_hdr;
-
- cmap_hdr = (CMAP_HDR *)act->data;
- imagec = cmap_hdr->cmap_size;
- cptr = (ColorReg *)cmap_hdr->data;
-
- off = x11_cmap_size - imagec;
- for(j=0;j<imagec;j++)
- {
- defs[j].pixel = off+j;
- defs[j].red = cptr[j].red << 8;
- defs[j].green = cptr[j].green << 8;
- defs[j].blue = cptr[j].blue << 8;
- defs[j].flags = DoRed | DoGreen | DoBlue;
- cmap[off+j].red = cptr[j].red;
- cmap[off+j].green = cptr[j].green;
- cmap[off+j].blue = cptr[j].blue;
- }
- XStoreColors(theDisp,theCmap,defs,imagec);
- XFlush(theDisp);
- }
- break;
- /*
- * Display an Image. Assumed to by imagex by imagey in size.
- */
- case ACT_IMAGE:
-
- theImage->data = act->data;
-
- XPutImage(theDisp,mainW,theGC,theImage,0,0,0,0,
- imagex,disp_y);
- XFlush(theDisp);
- cycle_wait = 1;
- screen_updated = TRUE;
- break;
- /*
- * Resize Window
- */
- case ACT_SIZE:
- {
- SIZE_HDR *size_hdr;
-
- size_hdr = (SIZE_HDR *)act->data;
- imagex = size_hdr->imagex;
- imagey = size_hdr->imagey;
- if (anim_flags & ANIM_LACE)
- disp_y = size_hdr->imagey/2;
- else
- disp_y = size_hdr->imagey;
- theImage->height = disp_y;
- theImage->width = imagex;
- theImage->bytes_per_line = imagex * x11_bytes_pixel;
- }
- break;
- /*
- * Lower Color Intensity by 1/16.
- */
- case ACT_FADE:
- {
- int off,j;
-
- off = x11_cmap_size - imagec;
- for(j=0;j<imagec;j++)
- {
- if (cmap[off+j].red <= 16) cmap[off+j].red = 0;
- else cmap[off+j].red -= 16;
- if (cmap[off+j].green <= 16) cmap[off+j].green = 0;
- else cmap[off+j].green -= 16;
- if (cmap[off+j].blue <= 16) cmap[off+j].blue = 0;
- else cmap[off+j].blue -= 16;
-
- defs[j].pixel = off+j;
- defs[j].red = cmap[off+j].red << 8;
- defs[j].green = cmap[off+j].green << 8;
- defs[j].blue = cmap[off+j].blue << 8;
- defs[j].flags = DoRed | DoGreen | DoBlue;
- }
- XStoreColors(theDisp,theCmap,defs,imagec);
- XFlush(theDisp);
- }
- screen_updated = TRUE;
- break;
- /*
- * A REGION display only part of an IMAGE.
- */
- case ACT_REGION:
- {
- ACT_REGION_HDR *act_reg_hdr;
-
- act_reg_hdr = (ACT_REGION_HDR *)(act->data);
-
- theImage->data = (char *)(act_reg_hdr->data);
-
- if (anim_flags & ANIM_LACE)
- {
- XPutImage(theDisp,mainW,theGC,theImage,
- act_reg_hdr->xpos, act_reg_hdr->ypos/2,
- act_reg_hdr->xpos, act_reg_hdr->ypos/2,
- act_reg_hdr->xsize, act_reg_hdr->ysize/2 );
- }
- else
- {
- XPutImage(theDisp,mainW,theGC,theImage,
- act_reg_hdr->xpos, act_reg_hdr->ypos,
- act_reg_hdr->xpos, act_reg_hdr->ypos,
- act_reg_hdr->xsize, act_reg_hdr->ysize );
- }
- XFlush(theDisp);
- cycle_wait = 1;
- }
- screen_updated = TRUE;
- break;
- /*
- * Act upon IFF Color Cycling chunk.
- * currently we don't color cycling during animations. will be fixed.
- */
- case ACT_IFF_CRNG:
- {
- CRNG_HDR *crng;
-
- crng = (CRNG_HDR *)act->data;
- if ( (crng->active & CRNG_ACTIVE)
- && (crng->low < crng->high)
- && (crng->rate != 0)
- && (anim_flags & ANIM_CYCLE)
- && (cycle_on_flag)
- )
- {
- cycle_cnt++;
- XtAppAddTimeOut(theContext,
- (int)(CRNG_INTERVAL/(crng->rate)),Cycle_It, crng);
- }
-
- }
- break;
- /*
- * FLI BRUN chunk.
- */
- case ACT_FLI_BRUN:
- Decode_Fli_BRUN(act->data,pic);
- theImage->data = pic;
- XPutImage(theDisp,mainW,theGC,theImage,0,0,0,0,
- imagex,disp_y);
- XFlush(theDisp);
- screen_updated = TRUE;
- break;
- /*
- * FLI BRUN chunk
- */
- case ACT_FLI_LC:
- {
- ACT_FLI_LC_HDR *fli_lc_hdr;
-
- fli_lc_hdr = (ACT_FLI_LC_HDR *)(act->data);
- Decode_Fli_LC( fli_lc_hdr->data, pic, fli_lc_hdr);
- theImage->data = pic;
- XPutImage(theDisp,mainW,theGC,theImage,
- fli_lc_hdr->xpos, fli_lc_hdr->ypos,
- fli_lc_hdr->xpos, fli_lc_hdr->ypos,
- fli_lc_hdr->xsize, fli_lc_hdr->ysize );
- XFlush(theDisp);
- }
- screen_updated = TRUE;
- break;
- /*
- * FLI_COLOR not supported. Actually it become a CMAP when read in.
- */
- case ACT_FLI_COLOR:
- fprintf(stderr,"fli_color not supported\n");
- break;
- /*
- * FLI COPY chunk
- */
- case ACT_FLI_COPY:
- theImage->data = act->data;
- XPutImage(theDisp,mainW,theGC,theImage,0,0,0,0,
- imagex,disp_y);
- XFlush(theDisp);
- screen_updated = TRUE;
- break;
- /*
- * Display Image of color 0.
- */
- case ACT_FLI_BLACK:
- memset(im_buff0,0x00,image_size);
- theImage->data = im_buff0;
- XPutImage(theDisp,mainW,theGC,theImage,0,0,0,0,
- imagex,disp_y);
- XFlush(theDisp);
- screen_updated = TRUE;
- break;
- /*
- * Display IFF body. Note that both buffers are set to this body.
- * this is necessary since next delta works on 2nd buffer.
- */
- case ACT_IFF_BODY:
-
- memcpy(im_buff0,act->data,image_size);
- memcpy(im_buff1,act->data,image_size);
- if (anim_flags & ANIM_HAM)
- {
- IFF_HAM_To_332(act->data,hbuff);
- theImage->data = hbuff;
- }
- else
- {
- theImage->data = act->data;
- }
-
- XPutImage(theDisp,mainW,theGC,theImage,0,0,
- 0,0,imagex,disp_y);
- XFlush(theDisp);
- cycle_wait = 1;
- old_dlta[0].minx = old_dlta[1].minx = 0;
- old_dlta[0].miny = old_dlta[1].miny = 0;
- old_dlta[0].maxx = old_dlta[1].maxx = imagex;
- old_dlta[0].maxy = old_dlta[1].maxy = imagey;
- screen_updated = TRUE;
- break;
- /*
- * Handle IFF anim op 5.
- */
- case ACT_IFF_DLTA5:
- {
- ACT_IFF_DLTA_HDR *iff_dlta_hdr;
-
- iff_dlta_hdr = (ACT_IFF_DLTA_HDR *)(act->data);
- IFF_Delta5(im_buff0,iff_dlta_hdr->data,iff_dlta_hdr);
-
- /* This mess keeps track of the largest rectangle needed to
- * display all changes. Since things are double buffered, the
- * min/maxes of the corners of the current and previous two
- * images are taken. If the animation is in single step mode
- * it's best to display the entire image.
- */
- if ((anim_running==FALSE) || (anim_forward_flag==FALSE))
- {
- old_dlta[0].minx = old_dlta[1].minx = 0;
- old_dlta[0].miny = old_dlta[1].miny = 0;
- old_dlta[0].maxx = old_dlta[1].maxx = imagex;
- old_dlta[0].maxy = old_dlta[1].maxy = imagey;
- }
- else
- {
- old_dlta[0].minx =
- MIN(old_dlta[0].minx,iff_dlta_hdr->minx);
- old_dlta[0].miny =
- MIN(old_dlta[0].miny,iff_dlta_hdr->miny);
- old_dlta[0].maxx =
- MAX(old_dlta[0].maxx,iff_dlta_hdr->maxx);
- old_dlta[0].maxy =
- MAX(old_dlta[0].maxy,iff_dlta_hdr->maxy);
- old_dlta[1].minx =
- MIN(old_dlta[1].minx,old_dlta[0].minx);
- old_dlta[1].miny =
- MIN(old_dlta[1].miny,old_dlta[0].miny);
- old_dlta[1].maxx =
- MAX(old_dlta[1].maxx,old_dlta[0].maxx);
- old_dlta[1].maxy =
- MAX(old_dlta[1].maxy,old_dlta[0].maxy);
- }
-
- if (anim_flags & ANIM_HAM)
- {
- IFF_HAM_To_332(pic,hbuff);
- theImage->data = hbuff;
- }
- else
- {
- theImage->data = im_buff0;
- }
-
- if (anim_flags & ANIM_LACE)
- {
- XPutImage(theDisp,mainW,theGC,theImage,
- old_dlta[1].minx, old_dlta[1].miny/2,
- old_dlta[1].minx, old_dlta[1].miny/2,
- old_dlta[1].maxx - old_dlta[1].minx,
- (old_dlta[1].maxy - old_dlta[1].miny)/2 );
- }
- else XPutImage(theDisp,mainW,theGC,theImage,
- old_dlta[1].minx, old_dlta[1].miny,
- old_dlta[1].minx, old_dlta[1].miny,
- old_dlta[1].maxx - old_dlta[1].minx,
- old_dlta[1].maxy - old_dlta[1].miny );
- XFlush(theDisp);
- pic = im_buff0; im_buff0 = im_buff1; im_buff1 = pic;
-
- /* Throw out oldest rectangle and store current
- * you get the idea.
- */
- old_dlta[1].minx = old_dlta[0].minx;
- old_dlta[1].miny = old_dlta[0].miny;
- old_dlta[1].maxx = old_dlta[0].maxx;
- old_dlta[1].maxy = old_dlta[0].maxy;
- old_dlta[0].minx = iff_dlta_hdr->minx;
- old_dlta[0].miny = iff_dlta_hdr->miny;
- old_dlta[0].maxx = iff_dlta_hdr->maxx;
- old_dlta[0].maxy = iff_dlta_hdr->maxy;
- }
- screen_updated = TRUE;
- break;
- /*
- * Handle IFF anim op 3 compressed actions.
- * NOTE: eventually put in largest rectangle optimization.
- */
- case ACT_IFF_DLTA3:
- {
- ACT_IFF_DLTA_HDR *iff_dlta_hdr;
-
- iff_dlta_hdr = (ACT_IFF_DLTA_HDR *)(act->data);
- IFF_Delta3(im_buff0, iff_dlta_hdr->data);
- if (anim_flags & ANIM_HAM)
- {
- IFF_HAM_To_332(pic,hbuff);
- theImage->data = hbuff;
- }
- else
- {
- theImage->data = im_buff0;
- }
-
- XPutImage(theDisp,mainW,theGC,theImage,0,0,0,0,
- imagex,disp_y);
- XFlush(theDisp);
- pic = im_buff0; im_buff0 = im_buff1; im_buff1 = pic;
- }
- screen_updated = TRUE;
- break;
- /*
- * Handle IFF anim opt J compressed actions.
- */
- case ACT_IFF_DLTAJ:
- {
- ACT_IFF_DLTA_HDR *iff_dlta_hdr;
-
- iff_dlta_hdr = (ACT_IFF_DLTA_HDR *)(act->data);
- IFF_DeltaJ(im_buff0,iff_dlta_hdr->data,iff_dlta_hdr);
-
- /* This mess keeps track of the largest rectangle needed to
- * display all changes. Since things are double buffered, the
- * min/maxes of the corners of the current and previous two
- * images are taken.
- */
- if ((anim_running==FALSE) || (anim_forward_flag==FALSE))
- {
- old_dlta[0].minx = old_dlta[1].minx = 0;
- old_dlta[0].miny = old_dlta[1].miny = 0;
- old_dlta[0].maxx = old_dlta[1].maxx = imagex;
- old_dlta[0].maxy = old_dlta[1].maxy = imagey;
- }
- else
- {
- old_dlta[0].minx =
- MIN(old_dlta[0].minx,iff_dlta_hdr->minx);
- old_dlta[0].miny =
- MIN(old_dlta[0].miny,iff_dlta_hdr->miny);
- old_dlta[0].maxx =
- MAX(old_dlta[0].maxx,iff_dlta_hdr->maxx);
- old_dlta[0].maxy =
- MAX(old_dlta[0].maxy,iff_dlta_hdr->maxy);
- old_dlta[1].minx =
- MIN(old_dlta[1].minx,old_dlta[0].minx);
- old_dlta[1].miny =
- MIN(old_dlta[1].miny,old_dlta[0].miny);
- old_dlta[1].maxx =
- MAX(old_dlta[1].maxx,old_dlta[0].maxx);
- old_dlta[1].maxy =
- MAX(old_dlta[1].maxy,old_dlta[0].maxy);
- }
-
- if (anim_flags & ANIM_HAM)
- {
- IFF_HAM_To_332(pic,hbuff);
- theImage->data = hbuff;
- }
- else
- {
- theImage->data = im_buff0;
- }
-
- if (anim_flags & ANIM_LACE)
- {
- XPutImage(theDisp,mainW,theGC,theImage,
- old_dlta[1].minx, old_dlta[1].miny/2,
- old_dlta[1].minx, old_dlta[1].miny/2,
- old_dlta[1].maxx - old_dlta[1].minx,
- (old_dlta[1].maxy - old_dlta[1].miny)/2 );
- }
- else XPutImage(theDisp,mainW,theGC,theImage,
- old_dlta[1].minx, old_dlta[1].miny,
- old_dlta[1].minx, old_dlta[1].miny,
- old_dlta[1].maxx - old_dlta[1].minx,
- old_dlta[1].maxy - old_dlta[1].miny );
- XFlush(theDisp);
- pic = im_buff0; im_buff0 = im_buff1; im_buff1 = pic;
-
- /* Throw out oldest rectangle and store current
- * you get the idea.
- */
- old_dlta[1].minx = old_dlta[0].minx;
- old_dlta[1].miny = old_dlta[0].miny;
- old_dlta[1].maxx = old_dlta[0].maxx;
- old_dlta[1].maxy = old_dlta[0].maxy;
- old_dlta[0].minx = iff_dlta_hdr->minx;
- old_dlta[0].miny = iff_dlta_hdr->miny;
- old_dlta[0].maxx = iff_dlta_hdr->maxx;
- old_dlta[0].maxy = iff_dlta_hdr->maxy;
- }
- screen_updated = TRUE;
- break;
- /*
- * Handle IFF anim op l(small L not one 1) compressed actions.
- * NOTE: eventually put in largest rectangle optimization.
- */
- case ACT_IFF_DLTAl:
- {
- ACT_IFF_DLTA_HDR *iff_dlta_hdr;
-
- iff_dlta_hdr = (ACT_IFF_DLTA_HDR *)(act->data);
- IFF_Deltal(im_buff0, (short *)iff_dlta_hdr->data,
- 1,iff_dlta_hdr);
- if (anim_flags & ANIM_HAM)
- {
- IFF_HAM_To_332(pic,hbuff);
- theImage->data = hbuff;
- }
- else
- {
- theImage->data = im_buff0;
- }
-
- XPutImage(theDisp,mainW,theGC,theImage,0,0,0,0,
- imagex,disp_y);
- XFlush(theDisp);
- pic = im_buff0; im_buff0 = im_buff1; im_buff1 = pic;
- }
- screen_updated = TRUE;
- break;
-
- /*
- * Update ham_map if it changes during an animation. ham_map is
- * needed in order to convert HAM images into 332.
- */
- case ACT_IFF_HMAP:
- {
- ColorReg *hptr;
- int i;
-
- hptr = (ColorReg *)act->data;
- for(i=0;i<HMAP_SIZE;i++)
- {
- ham_map[i].red = hptr[i].red;
- ham_map[i].green = hptr[i].green;
- ham_map[i].blue = hptr[i].blue;
- }
- }
- break;
- default:
- fprintf(stderr,"Unknown not supported %lx\n",act->type);
- } /* end of switch of action type */
- } /* end of action valid */
-
- /* Move on if we're running. If we're in single step mode and the update_flag
- * is set, we move on until the screen has been updated.
- */
- if (anim_running==TRUE)
- {
- if (anim_forward_flag == TRUE) Step_Action_Next();
- else Step_Frame_Prev();
- }
- else if ((update_flag == TRUE) && (screen_updated==FALSE))
- {
- if (anim_forward_flag == TRUE) Step_Frame_Next();
- else Step_Frame_Prev();
- }
- else return;
-
- /* Harry, what time is it?
- */
- t_frame_end = times(&tms3) - t_frame_start;
- t_frame_end *= 1000/HZ; /* convert to milliseconds */
-
- /* how much time left
- */
- t_frame_end = t_frame_int - t_frame_end;
- /* default to 1 ms, other wise 100 clk_tcks gives 10ms per tick.
- * NOTE: change all timing to milliseconds, not ticks.
- */
- if (t_frame_end <=0 ) t_frame_end = 1;
-
- XtAppAddTimeOut(theContext, t_frame_end, ShowAction, NULL);
- }
-
- Step_Action_Next()
- {
- /* Move to next frame
- */
- cur_frame++;
- if (debug_flag) fprintf(stderr,"frame = %ld\n",cur_frame);
-
- /* Are we at the end of an anim?
- */
- if ( (anim[cur_file].frame_lst[cur_frame] < 0)
- || (anim[cur_file].frame_lst[cur_frame] >= action_cnt) )
- {
- cur_frame = anim[cur_file].loop_frame;
-
- cur_floop++;
- if (debug_flag) fprintf(stderr," loop = %ld\n",cur_floop);
-
- /* Done looping animation. Move on to next file if present
- */
- if (cur_floop >= anim[cur_file].loop_num)
- {
- cur_floop = 0; /* Reset Loop Count */
-
- /* This is a special case check.
- * If more that one file, reset start_file, otherwise
- * if we're only displaying 1 animation jump to the loop_frame
- * which has already been set up above.
- */
- if (anim_cnt > 1)
- {
- start_file = 0;
- cur_frame = 0;
- } /* end of move on to next file/anim */
-
- cur_file++;
-
- if (cur_file >= anim_cnt)
- {
- cur_file=0;
- } /* end done with last file */
- if (debug_flag) fprintf(stderr," file = %ld\n",cur_file);
- } /* end done looping file */
- } /* end done with frames in file */
- }
-
- Step_Frame_Next()
- {
- /* Move to next frame
- */
- cur_frame++;
- if (debug_flag) fprintf(stderr,"frame = %ld\n",cur_frame);
-
- /* Are we at the end of an anim?
- */
- if ( (anim[cur_file].frame_lst[cur_frame] < 0)
- || (anim[cur_file].frame_lst[cur_frame] >= action_cnt) )
- {
- cur_frame = anim[cur_file].loop_frame;
- }
- }
-
- Step_Frame_Prev()
- {
- /* Move to next frame
- */
- cur_frame--;
- if (debug_flag) fprintf(stderr,"frame = %ld\n",cur_frame);
-
- /* Are we at the beginning of an anim?
- */
- if ( (anim[cur_file].frame_lst[cur_frame] < 0)
- || (anim[cur_file].frame_lst[cur_frame] >= action_cnt)
- || (cur_frame < anim[cur_file].loop_frame)
- || (cur_frame < 0)
- )
- {
- cur_frame = anim[cur_file].last_frame;
- }
- }
-
- Step_File_Next()
- {
- start_file = 0;
- cur_frame = 0;
- cur_floop = 0; /* used if things start up again */
-
- cur_file++;
- if (cur_file >= anim_cnt)
- {
- cur_file=0;
- } /* end done with last file */
-
- if (debug_flag) fprintf(stderr," file = %ld\n",cur_file);
- }
-
- Step_File_Prev()
- {
- start_file = 0;
- cur_frame = 0;
- cur_floop = 0; /* used if things start up again */
-
- cur_file--;
- if (cur_file < 0)
- {
- cur_file = anim_cnt-1;
- } /* end done with last file */
-
- if (debug_flag) fprintf(stderr," file = %ld\n",cur_file);
- }
-
-
- /*
- * Simple routine to find out the file type. Defaults to FLI.
- */
- int Determine_Anim_Type(filename)
- char *filename;
- {
- if ( Is_IFF_File(filename) ) return(IFF_ANIM);
- if ( Is_GIF_File(filename) ) return(GIF_ANIM);
- if ( Is_TXT_File(filename) ) return(TXT_ANIM);
- return(FLI_ANIM);
- }
-
- void Cycle_It(crng, id)
- CRNG_HDR *crng;
- XtIntervalId *id;
- {
- int i,c_off,clow,chi;
- XColor tmp_def;
-
- if ((anim_flags & ANIM_CYCLE) && cycle_on_flag)
- XtAppAddTimeOut(theContext,(int)(CRNG_INTERVAL/(crng->rate)),Cycle_It, crng);
- else cycle_cnt--;
-
- c_off = x11_cmap_size - imagec;
- clow = crng->low;
- chi = crng->high;
-
- if (crng->active & CRNG_REVERSE)
- {
- tmp_def = defs[clow];
- for (i = clow; i < chi; i++) defs[i] = defs[i + 1];
- defs[chi] = tmp_def;
- }
- else
- {
- tmp_def = defs[chi];
- for (i = chi; i > clow; i--) defs[i] = defs[i - 1];
- defs[clow] = tmp_def;
- }
-
- for (i = clow; i <= chi; i++) defs[i].pixel = i+c_off;
-
- XStoreColors(theDisp,theCmap,&defs[clow],(chi - clow + 1) );
- XFlush(theDisp);
- }
-
-